#!/usr/bin/env python3
"""
简化版专业领域资讯服务启动脚本
只使用核心依赖，避免复杂的安装问题
"""

import os
import sys
import subprocess
import platform
from pathlib import Path
import sqlite3
import json
from datetime import datetime

class SimpleStarter:
    def __init__(self):
        self.project_root = Path(__file__).parent
        self.data_dir = self.project_root / "data"
        self.data_dir.mkdir(exist_ok=True)
        
        self.system = platform.system().lower()
        print(f"🖥️  检测到操作系统: {self.system}")
    
    def check_minimal_dependencies(self):
        """检查最小依赖"""
        print("🔍 检查最小依赖...")
        
        required_modules = [
            "fastapi",
            "uvicorn", 
            "pydantic",
            "requests",
            "feedparser"
        ]
        
        missing_modules = []
        
        for module in required_modules:
            try:
                __import__(module)
                print(f"✅ {module}")
            except ImportError:
                print(f"❌ {module} - 缺失")
                missing_modules.append(module)
        
        if missing_modules:
            print(f"\n⚠️  缺失模块: {', '.join(missing_modules)}")
            print("正在安装缺失的依赖...")
            
            for module in missing_modules:
                try:
                    print(f"安装 {module}...")
                    subprocess.run([sys.executable, "-m", "pip", "install", module], 
                                 check=True, capture_output=True)
                    print(f"✅ {module} 安装成功")
                except subprocess.CalledProcessError as e:
                    print(f"❌ {module} 安装失败: {e}")
                    return False
        
        print("✅ 所有依赖检查通过")
        return True
    
    def create_simple_backend(self):
        """创建简化的后端"""
        print("🔧 创建简化后端...")
        
        backend_dir = self.project_root / "simple_backend"
        backend_dir.mkdir(exist_ok=True)
        
        # 创建简化的main.py
        main_content = '''from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
import sqlite3
import json
import feedparser
from datetime import datetime
from typing import List, Dict, Any
from pathlib import Path

app = FastAPI(title="专业领域资讯服务", version="1.0.0")

# CORS配置
app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:3000"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 数据库路径
DB_PATH = "data/news.db"

def init_db():
    """初始化数据库"""
    conn = sqlite3.connect(DB_PATH)
    cursor = conn.cursor()
    
    # 创建文章表
    cursor.execute("""
        CREATE TABLE IF NOT EXISTS articles (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            title TEXT NOT NULL,
            content TEXT,
            summary TEXT,
            url TEXT,
            source TEXT NOT NULL,
            category TEXT,
            keywords TEXT,
            created_at TEXT DEFAULT CURRENT_TIMESTAMP
        )
    """)
    
    # 创建关键词表
    cursor.execute("""
        CREATE TABLE IF NOT EXISTS keywords (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            keyword TEXT UNIQUE NOT NULL,
            category TEXT,
            is_active INTEGER DEFAULT 1,
            created_at TEXT DEFAULT CURRENT_TIMESTAMP
        )
    """)
    
    # 插入默认关键词
    default_keywords = [
        ("人工智能", "ai"),
        ("机器学习", "ai"),
        ("深度学习", "ai"),
        ("区块链", "tech"),
        ("云计算", "tech")
    ]
    
    for keyword, category in default_keywords:
        cursor.execute("""
            INSERT OR IGNORE INTO keywords (keyword, category)
            VALUES (?, ?)
        """, (keyword, category))
    
    conn.commit()
    conn.close()

@app.on_event("startup")
async def startup_event():
    """启动时初始化"""
    print("🚀 启动专业领域资讯服务...")
    init_db()

@app.get("/")
async def root():
    return {"message": "专业领域资讯服务", "version": "1.0.0"}

@app.get("/api/keywords")
async def get_keywords():
    """获取关键词列表"""
    conn = sqlite3.connect(DB_PATH)
    cursor = conn.cursor()
    cursor.execute("SELECT * FROM keywords WHERE is_active = 1")
    keywords = []
    for row in cursor.fetchall():
        keywords.append({
            "id": row[0],
            "keyword": row[1],
            "category": row[2],
            "is_active": bool(row[3]),
            "created_at": row[4]
        })
    conn.close()
    return keywords

@app.post("/api/keywords")
async def add_keyword(keyword: str, category: str = "general"):
    """添加关键词"""
    conn = sqlite3.connect(DB_PATH)
    cursor = conn.cursor()
    try:
        cursor.execute("""
            INSERT INTO keywords (keyword, category)
            VALUES (?, ?)
        """, (keyword, category))
        conn.commit()
        conn.close()
        return {"message": "关键词添加成功"}
    except sqlite3.IntegrityError:
        conn.close()
        raise HTTPException(status_code=400, detail="关键词已存在")

@app.get("/api/articles")
async def get_articles(limit: int = 50):
    """获取文章列表"""
    conn = sqlite3.connect(DB_PATH)
    cursor = conn.cursor()
    cursor.execute("""
        SELECT * FROM articles 
        ORDER BY created_at DESC 
        LIMIT ?
    """, (limit,))
    articles = []
    for row in cursor.fetchall():
        articles.append({
            "id": row[0],
            "title": row[1],
            "content": row[2],
            "summary": row[3],
            "url": row[4],
            "source": row[5],
            "category": row[6],
            "keywords": json.loads(row[7]) if row[7] else [],
            "created_at": row[8]
        })
    conn.close()
    return articles

@app.post("/api/collect")
async def collect_articles():
    """收集RSS文章"""
    rss_sources = {
        "nature": "https://www.nature.com/rss/current_aw.xml",
        "arxiv_ai": "http://export.arxiv.org/rss/cs.AI",
        "techcrunch": "https://techcrunch.com/feed/"
    }
    
    collected = 0
    conn = sqlite3.connect(DB_PATH)
    cursor = conn.cursor()
    
    for source_name, url in rss_sources.items():
        try:
            feed = feedparser.parse(url)
            for entry in feed.entries[:10]:
                # 检查是否已存在
                cursor.execute("SELECT COUNT(*) FROM articles WHERE url = ?", (entry.get("link", ""),))
                if cursor.fetchone()[0] == 0:
                    cursor.execute("""
                        INSERT INTO articles (title, content, summary, url, source, category)
                        VALUES (?, ?, ?, ?, ?, ?)
                    """, (
                        entry.get("title", ""),
                        entry.get("summary", ""),
                        entry.get("summary", "")[:500],
                        entry.get("link", ""),
                        source_name,
                        "rss"
                    ))
                    collected += 1
        except Exception as e:
            print(f"获取 {source_name} 失败: {e}")
    
    conn.commit()
    conn.close()
    
    return {"message": f"收集完成，新增 {collected} 篇文章"}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)
'''
        
        with open(backend_dir / "main.py", 'w', encoding='utf-8') as f:
            f.write(main_content)
        
        print("✅ 简化后端创建完成")
        return True
    
    def create_simple_frontend(self):
        """创建简化的前端"""
        print("🔧 创建简化前端...")
        
        frontend_dir = self.project_root / "simple_frontend"
        frontend_dir.mkdir(exist_ok=True)
        
        # 创建package.json
        package_json = {
            "name": "simple-news-frontend",
            "version": "1.0.0",
            "private": True,
            "dependencies": {
                "react": "^18.2.0",
                "react-dom": "^18.2.0",
                "react-scripts": "5.0.1",
                "axios": "^1.4.0"
            },
            "scripts": {
                "start": "react-scripts start",
                "build": "react-scripts build"
            },
            "browserslist": {
                "production": [">0.2%", "not dead", "not op_mini all"],
                "development": ["last 1 chrome version", "last 1 firefox version", "last 1 safari version"]
            },
            "proxy": "http://localhost:8000"
        }
        
        with open(frontend_dir / "package.json", 'w', encoding='utf-8') as f:
            json.dump(package_json, f, indent=2)
        
        # 创建public目录
        public_dir = frontend_dir / "public"
        public_dir.mkdir(exist_ok=True)
        
        with open(public_dir / "index.html", 'w', encoding='utf-8') as f:
            f.write('''<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>专业领域资讯服务</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>''')
        
        # 创建src目录
        src_dir = frontend_dir / "src"
        src_dir.mkdir(exist_ok=True)
        
        # 创建App.js
        app_js = '''import React, { useState, useEffect } from 'react';
import axios from 'axios';
import './App.css';

function App() {
  const [keywords, setKeywords] = useState([]);
  const [articles, setArticles] = useState([]);
  const [newKeyword, setNewKeyword] = useState('');
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    loadKeywords();
    loadArticles();
  }, []);

  const loadKeywords = async () => {
    try {
      const response = await axios.get('/api/keywords');
      setKeywords(response.data);
    } catch (error) {
      console.error('加载关键词失败:', error);
    }
  };

  const loadArticles = async () => {
    try {
      const response = await axios.get('/api/articles');
      setArticles(response.data);
    } catch (error) {
      console.error('加载文章失败:', error);
    }
  };

  const addKeyword = async () => {
    if (!newKeyword.trim()) return;
    
    try {
      await axios.post('/api/keywords', { keyword: newKeyword });
      setNewKeyword('');
      loadKeywords();
    } catch (error) {
      alert('添加关键词失败: ' + error.response?.data?.detail || error.message);
    }
  };

  const collectArticles = async () => {
    setLoading(true);
    try {
      await axios.post('/api/collect');
      loadArticles();
      alert('文章收集完成！');
    } catch (error) {
      alert('收集文章失败: ' + error.message);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="App">
      <header className="App-header">
        <h1>专业领域资讯服务</h1>
      </header>
      
      <main>
        <section className="keywords-section">
          <h2>关键词管理</h2>
          <div className="add-keyword">
            <input
              type="text"
              value={newKeyword}
              onChange={(e) => setNewKeyword(e.target.value)}
              placeholder="输入关键词"
            />
            <button onClick={addKeyword}>添加</button>
          </div>
          <div className="keywords-list">
            {keywords.map(keyword => (
              <div key={keyword.id} className="keyword-item">
                <span>{keyword.keyword}</span>
                <span className="category">{keyword.category}</span>
              </div>
            ))}
          </div>
        </section>

        <section className="articles-section">
          <h2>文章列表</h2>
          <button onClick={collectArticles} disabled={loading}>
            {loading ? '收集中...' : '收集文章'}
          </button>
          <div className="articles-list">
            {articles.map(article => (
              <div key={article.id} className="article-item">
                <h3>{article.title}</h3>
                <p>{article.summary}</p>
                <div className="article-meta">
                  <span>来源: {article.source}</span>
                  <span>分类: {article.category}</span>
                </div>
                {article.url && (
                  <a href={article.url} target="_blank" rel="noopener noreferrer">
                    阅读原文
                  </a>
                )}
              </div>
            ))}
          </div>
        </section>
      </main>
    </div>
  );
}

export default App;'''
        
        with open(src_dir / "App.js", 'w', encoding='utf-8') as f:
            f.write(app_js)
        
        # 创建App.css
        app_css = '''.App {
  text-align: center;
  padding: 20px;
  max-width: 1200px;
  margin: 0 auto;
}

.App-header {
  background-color: #282c34;
  padding: 20px;
  color: white;
  margin-bottom: 30px;
  border-radius: 8px;
}

.App-header h1 {
  margin: 0;
}

main {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 30px;
}

section {
  background: #f5f5f5;
  padding: 20px;
  border-radius: 8px;
}

.add-keyword {
  display: flex;
  gap: 10px;
  margin-bottom: 20px;
}

.add-keyword input {
  flex: 1;
  padding: 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.add-keyword button {
  padding: 8px 16px;
  background: #007bff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.keywords-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.keyword-item {
  display: flex;
  justify-content: space-between;
  padding: 10px;
  background: white;
  border-radius: 4px;
  border: 1px solid #ddd;
}

.category {
  color: #666;
  font-size: 0.9em;
}

.articles-list {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.article-item {
  background: white;
  padding: 15px;
  border-radius: 8px;
  border: 1px solid #ddd;
  text-align: left;
}

.article-item h3 {
  margin: 0 0 10px 0;
  color: #333;
}

.article-item p {
  color: #666;
  margin: 0 0 15px 0;
}

.article-meta {
  display: flex;
  gap: 15px;
  margin-bottom: 10px;
  font-size: 0.9em;
  color: #888;
}

.article-item a {
  color: #007bff;
  text-decoration: none;
}

.article-item a:hover {
  text-decoration: underline;
}

button {
  padding: 10px 20px;
  background: #28a745;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  margin-bottom: 20px;
}

button:disabled {
  background: #6c757d;
  cursor: not-allowed;
}

@media (max-width: 768px) {
  main {
    grid-template-columns: 1fr;
  }
}'''
        
        with open(src_dir / "App.css", 'w', encoding='utf-8') as f:
            f.write(app_css)
        
        # 创建index.js
        index_js = '''import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);'''
        
        with open(src_dir / "index.js", 'w', encoding='utf-8') as f:
            f.write(index_js)
        
        # 创建index.css
        index_css = '''body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

code {
  font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
    monospace;
}'''
        
        with open(src_dir / "index.css", 'w', encoding='utf-8') as f:
            f.write(index_css)
        
        print("✅ 简化前端创建完成")
        return True
    
    def install_frontend_dependencies(self):
        """安装前端依赖"""
        print("\n📦 安装前端依赖...")
        
        frontend_dir = self.project_root / "simple_frontend"
        
        try:
            # 检查Node.js - 使用完整路径
            print("检查Node.js...")
            node_path = "C:\\nvm4w\\nodejs\\node.exe"
            npm_path = "C:\\nvm4w\\nodejs\\npm.cmd"
            
            # 检查Node.js是否存在
            if os.path.exists(node_path):
                print(f"✅ 找到Node.js: {node_path}")
                subprocess.run([node_path, "--version"], check=True, capture_output=True)
            else:
                # 尝试使用PATH中的node
                subprocess.run(["node", "--version"], check=True, capture_output=True)
            
            # 检查npm
            print("检查npm...")
            if os.path.exists(npm_path):
                print(f"✅ 找到npm: {npm_path}")
                subprocess.run([npm_path, "--version"], check=True, capture_output=True)
            else:
                # 尝试使用PATH中的npm
                subprocess.run(["npm", "--version"], check=True, capture_output=True)
            
            # 安装依赖
            print("安装前端依赖...")
            if os.path.exists(npm_path):
                result = subprocess.run([npm_path, "install"], cwd=frontend_dir, capture_output=True, text=True)
            else:
                result = subprocess.run(["npm", "install"], cwd=frontend_dir, capture_output=True, text=True)
            
            if result.returncode == 0:
                print("✅ 前端依赖安装完成")
                return True
            else:
                print(f"❌ npm install 失败: {result.stderr}")
                return False
                
        except subprocess.CalledProcessError as e:
            print(f"❌ 前端依赖安装失败: {e}")
            return False
        except FileNotFoundError:
            print("❌ 找不到Node.js或npm，请先安装Node.js")
            return False
    
    def create_start_scripts(self):
        """创建启动脚本"""
        print("\n⚙️  创建启动脚本...")
        
        if self.system == "windows":
            # Windows启动脚本
            start_script = '''@echo off
echo 启动专业领域资讯服务...
echo.

echo 启动后端服务...
start "后端服务" cmd /k "cd /d "%~dp0" && cd simple_backend && python main.py"

timeout /t 3 /nobreak >nul

echo 启动前端服务...
start "前端服务" cmd /k "cd /d "%~dp0" && cd simple_frontend && npm start"

echo.
echo 服务启动完成！
echo 前端地址: http://localhost:3000
echo 后端地址: http://localhost:8000
echo.
echo 按任意键退出...
pause >nul'''
            
            with open(self.project_root / "start_simple.bat", 'w', encoding='utf-8') as f:
                f.write(start_script)
        else:
            # Unix启动脚本
            start_script = '''#!/bin/bash
echo "启动专业领域资讯服务..."
echo ""

echo "启动后端服务..."
cd "$(dirname "$0")"
cd simple_backend
python main.py &
sleep 3

echo "启动前端服务..."
cd ../simple_frontend
npm start &
echo ""
echo "服务启动完成！"
echo "前端地址: http://localhost:3000"
echo "后端地址: http://localhost:8000"
echo ""
echo "按 Ctrl+C 停止服务"
wait'''
            
            start_script_path = self.project_root / "start_simple.sh"
            with open(start_script_path, 'w', encoding='utf-8') as f:
                f.write(start_script)
            os.chmod(start_script_path, 0o755)
        
        print("✅ 启动脚本创建完成")
        return True
    
    def run(self):
        """运行简化启动程序"""
        print("🚀 专业领域资讯服务 - 简化版启动程序")
        print("="*50)
        
        # 检查最小依赖
        if not self.check_minimal_dependencies():
            print("❌ 依赖检查失败")
            return False
        
        # 创建简化后端
        if not self.create_simple_backend():
            print("❌ 创建后端失败")
            return False
        
        # 创建简化前端
        if not self.create_simple_frontend():
            print("❌ 创建前端失败")
            return False
        
        # 安装前端依赖
        if not self.install_frontend_dependencies():
            print("❌ 安装前端依赖失败")
            return False
        
        # 创建启动脚本
        if not self.create_start_scripts():
            print("❌ 创建启动脚本失败")
            return False
        
        # 显示使用说明
        self.show_usage()
        
        return True
    
    def show_usage(self):
        """显示使用说明"""
        print("\n" + "="*60)
        print("🎉 简化版安装完成！")
        print("="*60)
        print("\n📖 使用说明:")
        print("1. 启动服务:")
        if self.system == "windows":
            print("   - 双击 'start_simple.bat' 启动")
        else:
            print("   - 运行 './start_simple.sh' 启动")
        
        print("\n2. 访问地址:")
        print("   - 前端界面: http://localhost:3000")
        print("   - 后端API: http://localhost:8000")
        
        print("\n3. 功能说明:")
        print("   - 添加关键词: 在界面中添加你关注的专业关键词")
        print("   - 收集文章: 点击'收集文章'按钮获取最新资讯")
        print("   - 浏览文章: 查看匹配关键词的最新文章")
        
        print("\n4. 数据存储:")
        print(f"   - 数据库文件: {self.data_dir / 'news.db'}")
        
        print("\n" + "="*60)
        print("🚀 开始使用你的专业领域资讯服务吧！")
        print("="*60)

if __name__ == "__main__":
    starter = SimpleStarter()
    success = starter.run()
    
    if success:
        print("\n✅ 简化版安装成功完成！")
        sys.exit(0)
    else:
        print("\n❌ 安装失败，请检查错误信息")
        sys.exit(1) 